package appapi.config;

import appapi.entity.basic.UserInfo;
import appapi.utils.JsonUtils;
import appapi.utils.JwtUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.*;

@Slf4j
@Component
public class ArgumentParamFilter implements Filter {
    /**
     *
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String token = httpRequest.getHeader("token");
        Long userId = JwtUtil.getUserIdByJwtToken(token);
        //log.info("filter获取用户Id={}", userId);
        //UserInfo user=JwtUtil.getUserInfo(token);
        HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(httpRequest) {
            @Override
            public String[] getParameterValues(String name) {
                if ("userId".equals(name)) {
                    return new String[]{userId.toString()};
                }
//                else if ("userName".equals(name)) {
//                    return  new String[]{user.getUsername().toString()};
//                }
                return super.getParameterValues(name);
            }

            @Override
            public Enumeration<String> getParameterNames() {
                Set<String> paramNames = new LinkedHashSet<>();
                paramNames.add("userId");
                Enumeration<String> names = super.getParameterNames();
                while (names.hasMoreElements()) {
                    paramNames.add(names.nextElement());
                }
                return Collections.enumeration(paramNames);
            }

            @Override
            public ServletInputStream getInputStream() {
                byte[] requestBody;
                try {
                    requestBody = StreamUtils.copyToByteArray(request.getInputStream());
                    Map map = JsonUtils.parse(new String(requestBody), Map.class);
                    map.put("userId", userId);
                    requestBody = JsonUtils.serialize(map).getBytes();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }

                final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);
                return new ServletInputStream() {
                    @Override
                    public int read() {
                        return bais.read();
                    }

                    @Override
                    public boolean isFinished() {
                        return false;
                    }

                    @Override
                    public boolean isReady() {
                        return true;
                    }

                    @Override
                    public void setReadListener(ReadListener readListener) {

                    }
                };
            }

        };
        filterChain.doFilter(requestWrapper, httpResponse);
    }
}
